import datetime
import json
import random
import re

from flask import request, current_app, make_response, jsonify, session

from . import passport_blue

# 功能，获取图片验证码
from ... import redis_store, db
from ...constants import IMAGE_CODE_REDIS_EXPIRES, SMS_CODE_REDIS_EXPIRES
from ...models import User
from ...utils.captcha.captcha import captcha
from ...utils.response_code import RET

# 退出登录
# 请求路径：/passport/logout
# 请求方式：POST
# 请求参数：无
# 返回值：errno,errmsg
@passport_blue.route("/logout",methods=["POST"])
def logout():
    # 1、清除session信息
    session.pop("user_id",None)
    session.pop("is_admin", None)
    # 2、返回响应
    return jsonify(errno=RET.OK,errmsg="退出成功")

# 登录用户
# 请求路径：/passprot/login
# 请求方式：POST
# 请求参数：mobile,password
# 返回值：errno,errmsg
@passport_blue.route("/login",methods=["POST"])
def login():
    # 1、参数获取
    mobile = request.json.get("mobile")
    password = request.json.get("password")
    # 2、校验参数，为空检验
    if not all([mobile,password]):
        return jsonify(errno=RET.PARAMERR,errmsg="参数不去")
    # 3、通过用户手机号，到数据库查询用户对象
    try:
        user = User.query.filter(User.mobile==mobile).first()
    except Exception as e:
        current_app.logger.eroor(e)
        return jsonify(errno=RET.DBERR,errmsg="查询失败")
    # 4、判断用户是否存在
    if not user:
        return jsonify(errno=RET.NODATA,errmsg="该用户不存在")
    # 5、校验密码是否正确
    if not user.check_password(password):
        return jsonify(errno=RET.DATAERR,errmsg="密码错误")
    # 6、将用户的登录信息保存在session中
    session["user_id"] = user.id
    # 6.1记录用户最后一次登录的时间
    user.last_login = datetime.datetime.now()
    # try:
    #     db.session.commit()
    # except Exception as e:
    #     current_app.logger.eroor(e)
    # 7、返回相应
    return jsonify(errno=RET.OK,errmsg="成功")

# 注册用户
# 请求路径：/passport/register
# 请求方式：POST
# 请求参数：mobile,sms_code,password
# 返回值:errno,errmsg
@passport_blue.route("/register",methods=["POST"])
def register():
    # 1、参数获取
    # json_data = request.data
    # dict_data = json.loads(json_data)
    dict_data = request.json
    mobile = dict_data.get("mobile")
    sms_code_content = dict_data.get("sms_code")
    password = dict_data.get("password")
    # 2、校验参数，为空检验
    if not all([mobile,sms_code_content,password]):
        return jsonify(errno=RET.PARAMERR,errmsg="参数不全")
    # 3、手机号作为key去除redis中的短信验证码
    try:
        redis_sms_code = redis_store.get("sms_code:%s" % mobile)
    except Exception as e:
        current_app.logger.eroor(e)
        return jsonify(errno=RET.DBERR,errmsg="redis短信验证码取出失败")
    # 4、判断短信验证码是否过期
    if not redis_sms_code:
        return jsonify(errno=RET.NODATA,errmsg="短信验证码已过期")
    # 5、判断短信验证码是否正确
    if sms_code_content!=redis_sms_code:
        return jsonify(errno=RET.DATAERR,errmsg="短信验证码填写错误")
    # 6、删除短信验证码
    try:
        redis_store.delete("sms_code:%s" % mobile)
    except Exception as e:
        current_app.logger.eroor(e)
        return jsonify(errno=RET.DBERR,errmsg="删除短信验证码失败")
    # 7、创建用户对象
    user = User()
    # 8、设置用户对象属性
    user.nick_name = mobile
    user.password = password # 密码加密
    user.mobile = mobile
    user.signature = "该用户很懒，什么都没写"
    # 9、保存用户到数据库
    try:
        db.session.add(user)
        db.session.commit()
    except Exception as e:
        current_app.logger.eroor(e)
        return jsonify(errno=RET.DBERR,errmsg="用户注册失败")
    return jsonify(errno=RET.OK,errmsg="注册成功")

# 功能：获取短信验证码
# 请求路径：/passport/sms_code
# 请求方式：get
# 请求参数：mobile,image_code,image_code_id
# 返回值：短信验证码
@passport_blue.route("/sms_code", methods=["POST"])
def sms_code():
    # 1、获取参数
    # json_data = request.data
    # dict_data = json.loads(json_data)
    dict_data = request.json
    mobile = dict_data.get('mobile')
    image_code_content = dict_data.get("image_code")
    image_code_id = dict_data.get("image_code_id")
    # 2、参数为空检验
    if not all([mobile, image_code_content, image_code_id]):
        return jsonify(errno=RET.PARAMERR, errmsg="参数不全")
    # 3、校验手机的格式
    if not re.match("1[3-9]\d{9}", mobile):
        return jsonify(errno=RET.DATAERR, errmsg="手机号格式不正确")

    # 4、校验参数，图片验证码
    try:
        redis_image_code = redis_store.get("image_code:%s" % image_code_id)
    except Exception as e:
        current_app.logger.eroor(e)
        return jsonify(errno=RET.DBERR, errmsg="操作redis失败")
        # print(e)
    # 5、判断图片验证码是否过期
    if not redis_image_code:
        return jsonify(errno=RET.NODATA, errmsg="图片验证码已经过期")
    # 6、判断图片验证码是否正确
    if image_code_content.upper() != redis_image_code.upper():
        return jsonify(errno=RET.DATAERR, errmsg="图片验证码错误")
    # 7、删除redis中的图片验证码
    try:
        redis_store.delete("image_code:%s" % image_code_id)
    except Exception as e:
        current_app.logger.eroor(e)
        return jsonify(errno=RET.DBERR, errmsg="删除redis验证码失败")
    # 8、发送短信
    sms_code_content = "%06d" % random.randint(0, 999999)
    current_app.logger.debug("短信验证码：%s" % sms_code_content)
    # 9、将验证码保存到redis中
    try:
        redis_store.set("sms_code:%s" % mobile, sms_code_content, SMS_CODE_REDIS_EXPIRES)
    except Exception as e:
        current_app.logger.eroor(e)
        return jsonify(errno=RET.DBERR, errmsg="短信验证码保存到redis失败")

    return jsonify(errno=RET.OK, errmsg="短信发送成功")


# 功能：获取图片验证码
# 请求路径：/passport/image_code
# 请求方式：get
# 请求参数：cur_id,pre_id
# 返回值：图片验证码
@passport_blue.route("/image_code")
def image_code():
    # 获取前端传递的参数
    cur_id = request.args.get("cur_id")
    pre_id = request.args.get("pre_id")
    # 调用generate_captcha获取图片验证码编号，验证码值，图片（二进制）
    name, text, image_data = captcha.generate_captcha()

    # 将图片验证码的值保存至redis
    try:
        redis_store.set("image_code:%s" % cur_id, text, IMAGE_CODE_REDIS_EXPIRES)

        if pre_id:
            redis_store.delete("image_code:%s" % pre_id)
    except Exception as e:
        current_app.logger.eroor(e)
        return "图片验证码操作失败"

    # 返回图片
    response = make_response(image_data)
    response.headers["Content-Type"] = "image/png"
    return image_data
